//---------------------------------------------------------------------------------
//Form1.cs - version 1.5.0.0rc
// My demo of IronPython.  Might be useful for testing and debugging Python script
// that will be used with Microsoft's IronPython.  The IronTextBox control was
// something I wrote to help me understand IronPython and third party Python script.
//
// WHAT'S NEW:
//  -Adding support for IronPython RC1.
//  -Added support for IronTextBox.dll - version 1.4.1.0b
//
//BY DOWNLOADING AND USING, YOU AGREE TO THE FOLLOWING TERMS:
//Copyright (c) 2006 by Joseph P. Socoloski III
//LICENSE
//If it is your intent to use this software for non-commercial purposes, 
//such as in academic research, this software is free and is covered under 
//the GNU GPL License, given here: <http://www.gnu.org/licenses/gpl.txt> 
//---------------------------------------------------------------------------------

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using IronPython.Compiler;
using IronPython.Hosting;
using IronPython.Modules;
using IronPython.Runtime;
using IronPython.Runtime.Exceptions;
using IronPython.Runtime.Calls;
using IronPython.Runtime.Types;
using IronPython.Runtime.Operations;
//using IronPython.CodeDom;
using UIIronTextBox;
using UIIronTextBox.Paths;
using UIIronTextBox.Utils;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
//using UIIronTextBox.IPEWrapper;

namespace myIronPythonDemo
{
    public partial class Form1 : Form
    {
        #region Form1 members
        /// <summary>
        /// UIIronTextBox.ConsoleControl member
        /// </summary>
        private UIIronTextBox.IronTextBoxControl irontextboxControl;

        /// <summary>
        /// A global PythonEngine for the Application.
        /// </summary>
        ScriptEngine global_engine = null;
        ScriptScope defaultScope = null;

        #endregion Form1 members

        /// <summary>
        /// Form1
        /// </summary>
        public Form1()
        {
            global_engine = PythonEngine.CurrentEngine;
            defaultScope = global_engine.Runtime.Host.DefaultScope;

            InitializeComponent();
        }

        #region Form1 methods
        /// <summary>
        /// OnFormLoad
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        private void Form1_Load(object sender, EventArgs e)
        {
            //Optional...
            irontextboxControl.WriteText("help\r\n");
            irontextboxControl.SimEnter();
        }

        /// <summary>
        /// Closes this demo app.
        /// </summary>
        private void btClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion Form1 methods

        #region myIronPythonDemo Click Methods
        /// <summary>
        /// Demostrates importing of modules from .Execute from an IronPython Tutorial script file.
        /// </summary>
        private void btfirstpytest_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            
            //Let the engine know what directories we are working in
          //  pe.AddToPath(UIIronTextBox.Paths.Python24Dirs.Python24_Lib);
          //  pe.AddToPath(UIIronTextBox.Paths.Python24Dirs.Python24_libs);

            try
            {
                //Catch the different IronPython path
                if (!File.Exists(UIIronTextBox.Paths.IronPythonDirs.IronPython_Tutorial + @"\first.py"))
                {
                    MessageBox.Show("File " + UIIronTextBox.Paths.IronPythonDirs.IronPython_Tutorial + @"\first.py path invalid.\r\nPlease browse to first.py in the IronPython Tutorial directory.");

                    //Browse to the first.py sample file and import it
                    OpenFileDialog ofd = new OpenFileDialog();
                    ofd.Filter = "Python files (*.py)|*.py|All files (*.*)|*.*";
                    ofd.ShowDialog();

                    //import sys into the current IronPython Engine
                    irontextboxControl.WriteText("import sys");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    //Add the users path to the engine
                    string mypath = Path.GetDirectoryName(Path.GetFullPath(ofd.FileName));
                    //pe.AddToPath(mypath);
                    irontextboxControl.WriteText("sys.path.append(\"" + mypath + "\")");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    //notify user of import...
                    irontextboxControl.WriteText("import " + Path.GetFileNameWithoutExtension(ofd.FileName));
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    //Execute the built-in dir() function,
                    irontextboxControl.WriteText("dir(" + Path.GetFileNameWithoutExtension(ofd.FileName) + ")"); 

                    //lists the contents of the IronPythonEngine environment. Notice the imported methods from first.py
                    //notify user of statement...
                    //irontextboxControl.WriteText(myIPList.ToCodeString());
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();
                    irontextboxControl.Update();

                    irontextboxControl.WriteText("first.add(1, 2)");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    irontextboxControl.WriteText(@"first.add(""my"", ""stringobject"")");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();
                }
                else
                {
                    //import sys into the current IronPython Engine
                    irontextboxControl.WriteText("import sys");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    //Add the IronPython Tutorial path to the engine...
                    irontextboxControl.WriteText("sys.path.append(\"" + UIIronTextBox.Paths.IronPythonDirs.IronPython_Tutorial + "\")");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    //Import the sample script module
                    irontextboxControl.WriteText("import first");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    ////lists the contents of the IronPythonEngine environment. Notice the imported methods from first.py
                    
                    irontextboxControl.WriteText("dir(first)"); //Execute the built-in dir() function,
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    irontextboxControl.WriteText("first.add(1, 2)");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();

                    irontextboxControl.WriteText(@"first.add(""my"", ""stringobject"")");
                    irontextboxControl.Update();
                    irontextboxControl.SimEnter();
                }
            }
            catch (Exception err)
            {
                CallTraceDialogbox myTraceDlg = new CallTraceDialogbox();
                myTraceDlg.ShowTracesDlg("btfirstpytest_Click", err);
            }
            Cursor.Current = Cursors.Default;
        }

        /// <summary>
        /// Demostrates importing of modules from .Execute from an IronPython Tutorial script file.
        /// </summary>
        private void btNetimport_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;

            //this method will use a seperate PythonEngine than IronTextBox's builtin PythonEngine
            //  for demo purposes
            ScriptEngine pe = PythonEngine.CurrentEngine;

            string[] paths = new string[] { UIIronTextBox.Paths.Python24Dirs.Python24_Lib, UIIronTextBox.Paths.Python24Dirs.Python24_libs, UIIronTextBox.Paths.IronPythonDirs.IronPython_Tutorial };
            //Let the engine know what directories we are working in
            //pe.AddToPath(UIIronTextBox.Paths.Python24Dirs.Python24_Lib);
            //pe.AddToPath(UIIronTextBox.Paths.Python24Dirs.Python24_libs);
            //pe.AddToPath(UIIronTextBox.Paths.IronPythonDirs.IronPython_Tutorial);
            pe.SetScriptSourceSearchPaths(paths);

            try
            {
                //Catch the different IronPython path
                if (!File.Exists(UIIronTextBox.Paths.IronPythonDirs.IronPython_Tutorial + @"\first.py"))
                {
                    MessageBox.Show("File "+UIIronTextBox.Paths.IronPythonDirs.IronPython_Tutorial + @"\first.py does not exist");
                }
                else
                {
                    //Create some Python code and execute it
                    pe.CreateScriptSourceFromString(@"
import System
from System.Collections.Specialized import *
textnode_list = (('apple', 1.0), ('red', 0.9), ('fruit', 0.8), ('car', 0.8), ('seat', 0.8))
forward_linktype_blacklist = ('car', 'seat')
new_list = filter(lambda x:x[0] not in forward_linktype_blacklist, textnode_list)
mySC = StringCollection()
mySC.Add('hello')
mySC.Add('from')
mySC.Add('StringCollection')",SourceCodeKind.Statements).Execute(defaultScope);

                    //Create a IronPython.Runtime.List and display it
                    List myIPList = new List();
                    myIPList = pe.CreateScriptSourceFromString("dir()",SourceCodeKind.Statements).Execute<List>(defaultScope); //Execute the built-in dir() function,
                    //lists the contents of the IronPythonEngine environment. Some imported from first.py
                    UIIronTextBox.Utils.Converts.MessageBoxIronPy(myIPList);

                    //Test my custom UIIronTextBox.Utils.Converts.MessageBoxIronPy (which excepts objects from IronPython)
                    UIIronTextBox.Utils.Converts.MessageBoxIronPy("This is my string.");

                    //Create a IronPython.Runtime.Dict and display it
                    PythonDictionary IPDic = new PythonDictionary();
                    IPDic.setdefault("key1", 0.4);
                    IPDic.setdefault("key2", 1.0);
                    IPDic.setdefault("key3", 0.9);
                    UIIronTextBox.Utils.Converts.MessageBoxIronPy(IPDic);

                    //Print the value of the variable in the python code
                    UIIronTextBox.Utils.Converts.MessageBoxIronPy(defaultScope.LookupVariable("textnode_list"));

                    //Print the value of the variable in the python code
                    UIIronTextBox.Utils.Converts.MessageBoxIronPy(defaultScope.LookupVariable("new_list"));

                    //Print the value of the variable in the python code
                    UIIronTextBox.Utils.Converts.MessageBoxIronPy(defaultScope.LookupVariable("mySC"));

                }
            }
            catch (Exception err)
            {
                CallTraceDialogbox myTraceDlg = new CallTraceDialogbox();
                myTraceDlg.ShowTracesDlg("btNetimport_Click", err);
            }
            Cursor.Current = Cursors.Default;
        }

        /// <summary>
        /// Demostrates importing of modules from montylingua.
        /// This is me just exploring montylingua and ConceptNet with IronPython
        /// </summary>
        private void btMontyLemmatiser_Click(object sender, EventArgs e)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;

                //this.global_engine.SetVariable("self", this);

                irontextboxControl.WriteText("newconsole");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("cls");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("paths");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("rew");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("m = MontyLemmatiser()");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("m.lemmatise_untagged_sentence(\"This is my new sentence\")");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("m.lemmatise_untagged_sentence(\"MontyREChunker will try and chunk this sentence.\")\r\n");
                irontextboxControl.SimEnter();

                Cursor.Current = Cursors.Default;
            }
            catch (Exception err)
            {
                CallTraceDialogbox myTraceDlg = new CallTraceDialogbox();
                myTraceDlg.ShowTracesDlg("button1_Click", err);
            }
        }

        /// <summary>
        /// Demostrates importing of modules from montylingua.
        /// This is me just exploring montylingua and ConceptNet with IronPython
        /// </summary>
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;

                //this.global_engine.SetVariable("self", this);

                irontextboxControl.WriteText("newconsole");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("cls");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("paths");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("import MontyREChunker");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("dir(MontyREChunker.MontyREChunker)");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("m = MontyREChunker.MontyREChunker()");
                irontextboxControl.SimEnter();
                irontextboxControl.WriteText("m.chunk(\"MontyREChunker will try and chunk this sentence.\")\r\n");
                irontextboxControl.SimEnter();

                Cursor.Current = Cursors.Default;
            }
            catch (Exception err)
            {
                CallTraceDialogbox myTraceDlg = new CallTraceDialogbox();
                myTraceDlg.ShowTracesDlg("button1_Click", err);
            }
        }


        #endregion myIronPythonDemo Click Methods

        #region misc Notes
        //import pdb; pdb.set_trace()  //place this in Python script to trace in IDLE

        //IDLE is Python's Tkinter-based Integrated DeveLopment Environment. http://www.python.org/idle/
        #endregion misc Notes
    }
}